package LearnAlgorithm.h_标准数学公式;

/*
等比数列{an}的通项公式为：an = a1 * q^(n - 1)
				    推广：an = am * q^(n - m)
前n项和公式为：Sn = a1 / (1 - q) - (a1 * q^n) / (1 - q) 
		    或    Sn = (q * an) / (q - 1) - a1 / (q - 1)
当q=1，特殊情况Sn = a1 * n
注意： 以上n均属于正整数。

熟记当q=1时
Sn = a1 * n
熟记当q=2,a1=1时
Sn = 2^n - 1
 */
public class b等比数列求和 {
	public static void main(String[] args) {
		int[] arr1 = new int[] {1,2,4,8,16};//31
		int[] arr2 = new int[] {3,9,27,81,243};//363
		int[] arr3 = new int[] {2,2,2,2,2};//10
		System.out.println(sumProportionalSequence(arr2));
		System.out.println(sumProportionalSequenceForan(arr2));
		System.out.println(sumSpecial(arr1));
		System.out.println(sumSpecialOne(arr3));
	}
	
	/**
	 * 适用于任何等比数列
	 * @param arr
	 * @return
	 */
	public static int sumProportionalSequence(int[] arr) {
		int n = arr.length;
		int a1 = arr[0];
		int an = arr[n - 1];
		int q = arr[1] / arr[0];
		return (int) (a1 / (1 - q) - (a1 * Math.pow(q, n)) / (1 - q));
	}
	
	/**
	 * 适用于任何等比数列
	 * @param arr
	 * @return
	 */
	public static int sumProportionalSequenceForan(int[] arr) {
		int n = arr.length;
		int a1 = arr[0];
		int an = arr[n - 1];
		int q = arr[1] / arr[0];
		return (int) (q * an) / (q - 1) - a1 / (q - 1);
	}
	
	/**
	 * q=2,a1=1; 
	 * @param arr
	 * @return
	 */
	public static int sumSpecial(int[] arr) {
		return (int) (Math.pow(2, arr.length) - 1);
	}
	
	/**
	 * q=1
	 * @param arr
	 * @return
	 */
	public static int sumSpecialOne(int[] arr) {
		return arr[0] * arr.length;
	}
}
